package cn.njupt.singleCircle;
//单向循环链表,需要修改的是add方法和remove方法
public class LinkedList<E> extends AbstractList<E> {

    private Node<E> first;


    private static class Node<E> {
        E element;
        Node<E> next;

        public Node(E element, Node next) {
            this.element = element;
            this.next = next;
        }
    }


    @Override
    public void clear() {
        size = 0;
        first = null;
    }

    private Node<E> getIndexNode(int index) {
        judgeIndexOutOfBounds(index);
        Node result = first;
        while (index > 0) {
            result = result.next;
            index--;
        }
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb=new StringBuilder();
        Node<E> node=first;
        sb.append("size="+size+",[");
        for (int i = 0; i <size; i++) {
            sb.append(node.element);
            if(i!=size-1){
                sb.append(",");
            }
            node=node.next;
        }
        sb.append("]");
        return sb.toString();
    }



    /**
     * 在指定位置插入元素
     *
     * @param index
     * @param element
     */
    @Override
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        if (index == 0) {
            Node<E> newFirstNode = new Node(element, first);
            Node<E> last= (size==0)?newFirstNode:getIndexNode(size-1);//如果里面没有元素
            first = newFirstNode;
            last.next=first; //last可能为null
        } else {
            Node prev = getIndexNode(index - 1);
            Node cur = new Node(element, prev.next);
            prev.next = cur;
        }
        size++;
    }

    @Override
    public void remove(int index) {
        judgeIndexOutOfBounds(index); //[0,size-1]
        if (index == 0) {
            //如果只有一个元素或者有多个元素只删除第一个，如果不会写先写普通的
            if(size==1){
                first=null;
            }else{
                Node<E> last = getIndexNode(size - 1);
                last.next=first.next;
                first=first.next;
            }
        } else {
            Node<E> preNode = getIndexNode(index - 1);
            preNode.next = preNode.next.next;
        }
        size--;
    }





    @Override
    public E set(int index, E element) {
        judgeIndexOutOfBounds(index);
        Node<E> oldNode = getIndexNode(index);
        oldNode.element = element;
        return oldNode.element;
    }

    @Override
    public E get(int index) {
        judgeIndexOutOfBounds(index);
        return getIndexNode(index).element;
    }


    @Override
    public int indexOf(E element) {
        Node<E> node = first;
        if (element == null) {
            for (int i = 0; i < size; i++) {
                if (node.element == null) return i;
                node = node.next;
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (element.equals(node.element)) return i;
                node = node.next;
            }
        }
        return ELEMENT_NOT_FOUND;
    }

}
